/*
* Copyright (C) 2020 ~ 2023 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#ifndef MK_MEDIA_SERVER_H
#define MK_MEDIA_SERVER_H
#include <MkUtil/MkLock.h>
#include <MkHttpMedia/MkHttpMediaServer.h>
#include <MkUtil/MkIni.h>

class CMkTimer;
class CMkEventPool;
class CMkRtmpServer;
class CMkHttpMediaServer;
class CMkGbMediaServer;
class CMkRtspServer;
class CMkRtpServerPool;
class CMkTimerPool;
class CMkMediaServer
{
    using MediaServerParser = Uint32(CMkMediaServer::*)(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkHttpResponseJsonCb& ResCb);
    typedef MkUnorderedMap<MkString, MediaServerParser>   MapParser;
public:
    CMkMediaServer(CMkEventPool* pEventPool, CMkTimer* pTimer);
    ~CMkMediaServer();
    Uint32 Init(int argc, char** argv);
    CMkTimer* GetTimer() { return m_pTimer; }
    Uint32 Start();
    const CMkIni& GetIniConfig() const { return m_ConfigIni; }
private:
    Uint32 Stop();
    Uint32 ReadConfig();
    Uint32 GetVersion(MkString& Version);
    Uint32 StartHttpServer();
    Uint32 StartGbServer();
    Uint32 StartRtspServer();
    Uint32 StartRtmpServer();
    Uint32 StartRtpPool();
private:
    Uint32 OnRequestJsonParse(const MkHttpMethod& Method, const MkString& Path, const MkMapString& MapQuery, const Json::Value& JsonReq, const MkHttpResponseJsonCb& cb);
    Uint32 OnMediaAdd(CMkMediaSource* pSource);
    Uint32 OnMediaDelete(const MkString& SourceSession);
    Uint32 OnMediaConsumerAdd(const MkString& SourceSession, CMkMediaConsume* pConsume, CMkMediaConsumer* pConsumer);
    Uint32 OnMediaConsumerClosed(const MkString& SourceSession, const MkMediaConsumeType& ConsumeType, const MkString& ConsumerSession);
    Uint32 OnMediaConsumerPlayCtrl(CMkMediaConsumer* pConsumer, const MkPlaybackControlType& ControlType, float fSpeed, Uint32 offsetSec);
    Uint32 OnMediaSourceGetParam(const MkString& Path, CMkVideoParam& VideoParam, CMkAudioParam& AudioParam, Uint32& Duration, Uint32& FileSize, MkString& SourceSession);
    Uint32 OnGetAuth(MkString& UserName, MkString& Password);
    void OnWsAccessed(CMkHttpSession* pSession);
    Uint32 DeleteSource(const MkString& SourceSession);
    Uint32 ClearSource();
private:
    Uint32 AddParser(const MkString& Path, const MkHttpMethod& Method, const MediaServerParser& Parser);
    MkString GetRequestStringValue(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkString& strKey);
    Uint32 GetRequestUint32Value(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkString& strKey);
    float GetRequestFloatValue(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkString& strKey);
    double GetRequestDoubleValue(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkString& strKey);
    BOOL GetRequestBooleanValue(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkString& strKey);
private:
    Uint32 GetVersionParse(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkHttpResponseJsonCb& ResCb);
    Uint32 GetConfigParse(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkHttpResponseJsonCb& ResCb);
    Uint32 SetConfigParse(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkHttpResponseJsonCb& ResCb);
    Uint32 GetWsAccessKeyParse(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkHttpResponseJsonCb& ResCb);
    Uint32 AddProxyStreamParse(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkHttpResponseJsonCb& ResCb);
    Uint32 GetMediaSourceParse(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkHttpResponseJsonCb& ResCb);
    Uint32 DeleteMediaSourceParse(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkHttpResponseJsonCb& ResCb);
    Uint32 GetMediaConumerParse(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkHttpResponseJsonCb& ResCb);

    Uint32 GetRtpPortRangeParse(const Json::Value& JsonReq, const MkMapString& MapQuery, const MkHttpResponseJsonCb& ResCb);
    Uint32 ShutDownParse(const Json::Value& JsonReq, const MkMap<MkString, MkString>& MapQuery, const MkHttpResponseJsonCb& ResCb);
    Uint32 RebootParse(const Json::Value& JsonReq, const MkMap<MkString, MkString>& MapQuery, const MkHttpResponseJsonCb& ResCb);

private:
    Uint32 WsNotifyMsg(const MkString& strAction, const Json::Value& JsonBody, CMkHttpSession* pSession = nullptr);
    Uint32 WsNotifyConfig(CMkHttpSession* pSession = nullptr);
    Uint32 WsGbRegServerInfo(CMkHttpSession* pSession = nullptr);
    Uint32 WsNotifyMediaInfo(CMkHttpSession* pSession = nullptr);
private:
    BOOL                    m_bReboot;
    CMkIni                  m_ConfigIni;
    MapParser               m_MapGetParser;
    MapParser               m_MapPutParser;
    MapParser               m_MapPostParser;
    MapParser               m_MapDeleteParser;

    CMkEventPool*           m_pEventPool;
    CMkTimer*               m_pTimer;
    CMkRtpServerPool*       m_pRtpPool;
    CMkHttpMediaServer*     m_pHttpMediaServer;
    CMkGbMediaServer*       m_pGbMediaServer;
    CMkRtmpServer*          m_pRtmpServer;
    CMkRtspServer*          m_pRtspServer;

    CMkRwLock                        m_MediaSourceLock;
    MkMap<MkString, CMkMediaSource*> m_MapMediaSource;
    MkMediaCallbacks        m_MediaCbs;

    MkString                m_NotifyMediaInfoTimer;
};

#endif
